package grammar.parser.stmt;

import error.processing.MyErrorProcessing;
import exp.parser.Cond;
import word.parser.WordElement;

public class WhileStmt extends Stmt {
    private final Cond cond;
    private final Stmt stmt;
    private boolean needBreak = false;

    public WhileStmt(Cond cond, Stmt stmt) {
        this.cond = cond;
        this.stmt = stmt;
    }

    public static WhileStmt buildWhileStmt() {
        assert getAnalyzingWord().getType() == WordElement.WordType.WHILETK;
        int whilePosition = getNowPosition();
        analyzeNextWord();
        assert getAnalyzingWord().getType() == WordElement.WordType.LPARENT;
        analyzeNextWord();
        Cond cond = Cond.buildCond();
        if (getAnalyzingWord().getType() != WordElement.WordType.RPARENT) {
            MyErrorProcessing.buildErrorProcessing(MyErrorProcessing.ErrorType.j,
                    getAnalyzingWord(-1));
        } else {
            analyzeNextWord();
        }

        getSemanticParser().addCycleLayerNum();

        Stmt stmt = Stmt.buildStmt();

        getSemanticParser().outCycle();

        return new WhileStmt(cond, stmt);
    }

    public void callBreak() {
        this.needBreak = true;
    }

    public void callContinue() {
        this.needBreak = false;
    }

    @Override
    public void execute() {
        getSemanticParser().addCycleLayerNum(this);
        while (cond.getValue() != 0 && !needBreak &&
                !getSemanticParser().isCallReturn()) {
            getSemanticParser().resetBreakOrContinue();
            stmt.execute();
        }
        needBreak = false;
        getSemanticParser().outCycle(this);
        getSemanticParser().resetBreakOrContinue();
    }
}
